﻿using System;
using System.Collections.Generic;
using System.Linq;
using Xc.DataAccess.DataBase.DeviceInfos.Models;
using System.Data;
using Microsoft.EntityFrameworkCore;
using Xc.DataAccess.Core;

namespace Xc.DataAccess.DataBase.DeviceInfos
{

    public abstract class TableInfoServiceCore<TDbContext>  where TDbContext : DbContext, IDbDevice
    {
        protected readonly IDbContextFactory<TDbContext> _dbContextFactory;

        public TableInfoServiceCore(IDbContextFactory<TDbContext> dbContextFactory)
        {
            _dbContextFactory = dbContextFactory;
        }

        /// <summary>
        /// 设置值,并记录历史数据
        /// </summary>
        /// <param name="valuePairs"></param>
        /// <param name="deviceId"></param>
        protected Result SetValue<T, THistory,TDb>(TDb db, DbSet<T> simple,DbSet<THistory> histories,Dictionary<string, UnitString> valuePairs, string deviceId) where T : class ,ITableInfo, IDeviceInfoId, new() where THistory :class,ITableInfo, IDeviceInfoId,IDateTimeCreate,new() where TDb:DbContext,IDbDevice
        {
            var dt = DateTime.Now;
            foreach (var item in valuePairs)
            {
                var device = db.DeviceInfos.Find(deviceId);
                if (device == null)
                {
                    return Result.Reject("不存在这样的设备编号");
                }
                var property = simple.Where(p => p.DeviceInfoId == item.Key).FirstOrDefault();
                if (property == null)
                {
                    simple.Add(new T { DeviceInfoId = deviceId, Name = item.Key, Value = item.Value });
                }
                else
                {
                    property.Value = item.Value;
                }
                histories.Add(new THistory { DateTimeCreate = dt, DeviceInfoId = deviceId, Value = item.Value, Name = item.Key });
            }
            return Result.From(db.SaveChanges(), (s) => s > 1);
        }
        /// <summary>
        /// 获取表信息
        /// </summary>
        /// <param name="datas"></param>
        /// <param name="autoAppendLastState"></param>
        /// <returns></returns>
        protected  DataTableInfo GetTableInfo<T>(T[] datas,bool autoAppendLastState) where T:ITableInfo,IDateTimeCreate
        {
            var columns = datas.Select(p => p.Name).GroupBy(p => p).Select(p => p.Key).ToArray();
            var infos = datas.GroupBy(p => p.DateTimeCreate).Select(p => new { DateTime = p.Key, Data = p.ToArray() }).ToArray();
            DataTableInfo dataTable = new DataTableInfo();
            dataTable.Columns.Add("dateTime");
            dataTable.Columns.AddRange(columns);
            for (int i = 0; i < infos.Count(); i++)
            {
                var item = infos[i];
                List<string> vs = new List<string>();
                vs.Add(item.DateTime.ToString("yyyy/MM/dd HH:mm:ss"));
                foreach (var pro in columns)
                {
                    var result = item.Data.Where(p => p.Name == pro && p.DateTimeCreate == item.DateTime).FirstOrDefault();
                    if (result != null)
                    {
                        vs.Add(result.Value);
                    }
                    else
                    {
                        vs.Add(String.Empty);
                    }
                }
                dataTable.Rows.Add(vs.ToArray());
            }
            if (autoAppendLastState == true)
            {
                for (int i = 0; i < dataTable.Rows.Count; i++)
                {
                    var row = dataTable.Rows[i];
                    for (int j = 0; j < row.Length; j++)
                    {
                        var cell = row[j];
                        if (string.IsNullOrEmpty(cell))
                        {
                            var final = dataTable.Rows.Select(p => p[j]).Take(i).LastOrDefault();
                            if (final != null)
                            {
                                row[j] = final;
                            }

                        }
                    }
                }
            }


            return dataTable;
        }
    }

}
